﻿using System;
using System.Drawing;
using System.Windows.Forms;
using PicGame.Res;
using PicGame.Utils;

namespace PicGame.UI
{
    public partial class FormMain : Form
    {
        private bool _isOver = false;
        private float _minWidth = 250;
        private float _minHeight = 250;
        private PointF _firstP = new PointF(10, 10);
        private int _rowCount = 5;
        private int _colCount = 5;
        private Lazy<FormImgs> _frmImgs = null;

        /// <summary>
        /// 切割图片的行数
        /// </summary>
        public int RowCount
        {
            get { return Math.Max(3, this._rowCount); }
            set { this._rowCount = value; }
        }

        /// <summary>
        /// 切割图片的列数
        /// </summary>
        public int ColCount
        {
            get { return Math.Max(3, this._colCount); }
            set { this._colCount = value; }
        }

        /// <summary>
        /// 要拼图的主图片
        /// </summary>
        public Bitmap Bmp { get; set; } = R.Get_Clock();

        public FormMain()
        {
            InitializeComponent();

            this.MouseWheel += new MouseEventHandler(this.FormMain_MouseWheel);
        }

        private void FormMain_MouseWheel(object sender, MouseEventArgs e)
        {
            this.panelMain.Focus();
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            this._frmImgs = new Lazy<FormImgs>(() => new FormImgs(this));

            var point = Point.Empty;
            var size = Size.Empty;

            if (Reg.Instance.LoadForm(out point, out size))
            {
                this.Location = point;
                this.Size = size;
            }

            this.Init();
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MSGBox.OKCancel("确定要退出游戏吗？") == DialogResult.Cancel)
            {
                e.Cancel = true;
                return;
            }

            if (this.WindowState != FormWindowState.Maximized && this.WindowState != FormWindowState.Minimized)
            {
                Reg.Instance.RegForm(this.Location, this.Size);
            }
        }

        private void picMain_Paint(object sender, PaintEventArgs e)
        {
            PicGameMain.Instance.PaintSubImgs(e.Graphics);
        }

        private void FormMain_Resize(object sender, EventArgs e)
        {
            this.Center();
        }

        private void panelMain_MouseDown(object sender, MouseEventArgs e)
        {
            this.picMain_MouseDown(null, new MouseEventArgs(e.Button, e.Clicks, 0, 0, e.Delta));
        }

        private void picMinImg_MouseDown(object sender, MouseEventArgs e)
        {
            this.picMinImg.Visible = false;
        }

        /// <summary>
        /// 通过鼠标操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void picMain_MouseDown(object sender, MouseEventArgs e)
        {
            this.picMinImg.Visible = false;

            if (e.Button == MouseButtons.Left)
            {
                this._isOver = this.IsGameOver();

                this.SetAttrs();

                if (this._isOver)
                {
                    return;
                }

                PicGameMain.Instance.MoveSubImg(
                    e.Location,
                    it =>
                    {
                        this.picMain.Invalidate(new Region(it.RectF));
                    });

                this.SetAttrs();

                this._isOver = this.IsGameOver();
            }
        }

        /// <summary>
        /// 通过键盘操作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormMain_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up ||
                e.KeyCode == Keys.Down ||
                e.KeyCode == Keys.Left ||
                e.KeyCode == Keys.Right ||
                e.KeyCode == Keys.F5 ||
                e.KeyCode == Keys.R)
            {
                this._isOver = this.IsGameOver();

                this.SetAttrs();

                if (this._isOver)
                {
                    return;
                }

                switch (e.KeyCode)
                {
                    case Keys.Up:
                        PicGameMain.Instance.MoveSubImg(
                            FX.SHANG,
                            it =>
                            {
                                this.picMain.Invalidate(new Region(it.RectF));
                            });
                        break;
                    case Keys.Down:
                        PicGameMain.Instance.MoveSubImg(
                            FX.XIA,
                            it =>
                            {
                                this.picMain.Invalidate(new Region(it.RectF));
                            });
                        break;
                    case Keys.Left:
                        PicGameMain.Instance.MoveSubImg(
                            FX.ZUO,
                            it =>
                            {
                                this.picMain.Invalidate(new Region(it.RectF));
                            });
                        break;
                    case Keys.Right:
                        PicGameMain.Instance.MoveSubImg(
                            FX.YOU,
                            it =>
                            {
                                this.picMain.Invalidate(new Region(it.RectF));
                            });
                        break;
                    case Keys.F5:
                        tsbtnNew_Click(null, null);
                        break;
                    case Keys.R:
                        tsbtnCX_Click(null, null);
                        break;
                    default:
                        break;
                }

                this.SetAttrs();

                this._isOver = this.IsGameOver();
            }
        }

        /// <summary>
        /// 重新开始游戏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbtnNew_Click(object sender, EventArgs e)
        {
            if (this._frmImgs.Value.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            this.Init(() => this.picMain.Invalidate());
        }

        /// <summary>
        /// 撤销到上步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbtnCX_Click(object sender, EventArgs e)
        {
            if (this._isOver)
            {
                return;
            }

            PicGameMain.Instance.GameBack(it =>
            {
                this.picMain.Invalidate(new Region(it.RectF));
                this.SetAttrs();
            });
        }

        /// <summary>
        /// 显示缩略图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tsbtnShowMinImg_Click(object sender, EventArgs e)
        {
            this.picMinImg.Focus();

            this.picMinImg.Visible = !this.picMinImg.Visible;
        }

        /// <summary>
        /// 判断图片是否拼还原
        /// </summary>
        /// <returns></returns>
        private bool IsGameOver()
        {
            if (PicGameMain.Instance.IsGameOver())
            {
                if (MSGBox.YesNo("恭喜您，您已成功过关，是否继续游戏？") == DialogResult.Yes)
                {
                    this.Init(() => { this.picMain.Invalidate(); });
                }

                return true;
            }

            return false;
        }

        /// <summary>
        /// 设置撤销按钮是否可用
        /// </summary>
        private void SetAttrs()
        {
            this.tsbtnCX.Enabled = !this._isOver && PicGameMain.Instance.GameStepCount > 0;

            this.tslbStepCount.Text = "游戏步数：" + PicGameMain.Instance.GameStepCount;
        }

        /// <summary>
        /// 初始化游戏
        /// </summary>
        /// <param name="action"></param>
        private void Init(Action action = null)
        {
            PicGameMain.Instance.Init(this._rowCount, this._colCount, this.Bmp, this._firstP, action);

            this.picMinImg.BackgroundImage = PicGameMain.Instance.GetMinImage2(this.Bmp, this._minWidth, this._minHeight, this._rowCount, this._colCount);

            this.Center();

            this.SetAttrs();
        }

        /// <summary>
        /// 使picturebox在panel中居中
        /// </summary>
        private void Center()
        {
            var p = new Point(0, 0);

            this.picMain.Size = new Size(this.Bmp.Width + 21, this.Bmp.Height + 21);

            if (this.picMain.Width < this.panelMain.Width)
            {
                p.X = (this.panelMain.Width - this.picMain.Width) / 2;
            }

            if (this.picMain.Height < this.panelMain.Height)
            {
                p.Y = (this.panelMain.Height - this.picMain.Height) / 2;
            }

            picMain.Location = new Point(p.X - panelMain.HorizontalScroll.Value, p.Y - panelMain.VerticalScroll.Value);
        }
    }
}